<template>
  <div ref="graphContainer" id="graphContainer"></div>
  <div
    id="hiddenContainer"
    style="visibility: hidden; position: absolute"
  ></div>
</template>
<script setup>
import { onMounted, ref, defineProps, onUnmounted } from "vue";
import G6 from "@antv/g6";
import { useLanguage } from "@/hooks/index";
// import domtoimage from "dom-to-image";
// import { htmlToPDF } from '@/utils/html2pdf'
import html2canvas from "html2canvas";
import jsPDF from "jspdf";

const { isEn, isCn, isArabic } = useLanguage();
const emits = defineEmits(["treeChartChage"]);

const props = defineProps({
  treeData: { type: Array, default: [] },
});

const spinning = ref(true);

const graphContainer = ref(null);
let graph = null;

onMounted(() => {
  if (props.treeData && props.treeData.length) {
    treeChart();
  }
});
const isCategory = (cfg) => {
  if (cfg.personalType === 0) {
    return `<div class="square-style-right-top positionOrange">
      ${cfg.name}
    </div>`;
  } else {
    return `<div class="square-style-right-top positionGreen">
      ${cfg.name}
    </div>`;
  }
};
const generateSonHtml = (children, hasOuterLine = false) => {
  if (!children) return "";

  let level = 0;

  let html = "";

  function generaHtml(kids, level) {
    if (!kids) return "";
    level++;

    let kidHtml = "";
    kids.forEach((cfg, idx) => {
      kidHtml += `
              <div class="outermost">
                ${
                  level === 1 && hasOuterLine
                    ? `
                    <div class="outermost-line">
                      <div class="top-line"></div>
                      ${
                        idx === kids.length - 1
                          ? ""
                          : `<div class="bottom-line"></div>`
                      }
                    </div>
                  `
                    : ""
                }
                <li class="hierarchy" data-level='${level}' last-index='${
        kids.length - 1
      }' index='${idx}'>
                  <div class="square-wrap">
                    ${
                      level > 1
                        ? `
                        <div class="line">
                          <div class="top-line"></div>
                          ${
                            idx === kids.length - 1
                              ? ""
                              : `<div class="bottom-line"></div>`
                          }
                        </div>
                      `
                        : ""
                    }
                    <div class="node square-style">
                      <div class="square-style-left">
                        <div class="square-style-left-top">${(cfg.employeeList && cfg.employeeList.length) || 0}</div>
                        <div class="square-style-left-bottom"> ${ cfg.rotation || '--' }</div>
                      </div>
                      <div class="square-style-right">
                        ${isCategory(cfg)}
                        ${
                          (cfg.employeeList &&
                            cfg.employeeList
                              .map((item) => {
                                return `<div class="square-style-right-bottom">${item.fullName.replace(
                                  /(.{19})/g,
                                  "$1\n"
                                )}(${item.rotationDesc || "--"})</div>`;
                              })
                              .join("")) ||
                          `<div class="square-style-right-bottom">--</div>`
                        }
                      </div>
                    </div>
                  </div>
                  ${
                    cfg.children && cfg.children.length
                      ? `<ul class="nodes">${generaHtml(
                          cfg.children,
                          level
                        )}</ul>`
                      : ""
                  }
                </li>
              </div>
      `;
    });

    return kidHtml;
  }

  html += `
      <ul class="nodes">
        ${generaHtml(children, level)}
      </ul>
    `;

  return html;
};

const getTopHtml = (cfg) => {
  return `
    <div class="top-box-html">
      <div class="diamond-style">
        <div class="diamond-top">${ cfg.employeeCount || 0 }</div>
        <div class="diamond-bottom">${ cfg.rotation || '--' }</div>
      </div>
      <div class="tox-box-diamond">
        <div class="diamond-title">
          ${
            isCn && cfg.nameZh
              ? cfg.nameZh
              : isArabic && cfg.nameAr
              ? cfg.nameAr
              : cfg.nameEn
          }
        </div>
        ${
          (cfg.leaderList &&
            cfg.leaderList
              .map((item) => {
                return `<div class="diamond-name">${item.fullName.replace(
                  /(.{19})/g,
                  "$1\n"
                )}(${item.rotationDesc || "--"})</div>`;
              })
              .join("")) ||
          `<div class="diamond-name">--</div>`
        }
      </div>
    </div>`;
};
const generateSonTopHtml = (children, hasOuterLine = false) => {
  if (!children) return "";

  let level = 0;

  let html = "";

  function generaHtml(kids, level) {
    if (!kids) return "";
    level++;

    let kidHtml = "";
    kids.forEach((cfg, idx) => {
      kidHtml += `
              <div class="outermost">
                ${
                  level === 1 && hasOuterLine
                    ? `
                    <div class="outermost-line">
                      ${ idx === 0 ? '<div class="top-line0"></div>': `<div class="top-line"></div>`}
                      <div class="bottom-line"></div>
                    </div>
                  `
                    : ""
                }
                <li class="hierarchy" data-level='${level}' last-index='${
        kids.length - 1
      }' index='${idx}'>
                  <div class="square-wrap">
                    ${
                      level > 1
                        ? `
                        <div class="line">
                          <div class="top-line"></div>
                          ${
                            idx === kids.length - 1
                              ? ""
                              : `<div class="bottom-line"></div>`
                          }
                        </div>
                      `
                        : ""
                    }
                    <div class="node square-style">
                      <div class="square-style-left">
                        <div class="square-style-left-top">${(cfg.employeeList && cfg.employeeList.length) || 0}</div>
                        <div class="square-style-left-bottom"> ${ cfg.rotation || '--' }</div>
                      </div>
                      <div class="square-style-right">
                        ${isCategory(cfg)}
                        ${
                          (cfg.employeeList &&
                            cfg.employeeList
                              .map((item) => {
                                return `<div class="square-style-right-bottom">${item.fullName.replace(
                                  /(.{19})/g,
                                  "$1\n"
                                )}(${item.rotationDesc || "--"})</div>`;
                              })
                              .join("")) ||
                          `<div class="square-style-right-bottom">--</div>`
                        }
                      </div>
                    </div>
                  </div>
                  ${
                    cfg.children && cfg.children.length
                      ? `<ul class="nodes">${generaHtml(
                          cfg.children,
                          level
                        )}</ul>`
                      : ""
                  }
                </li>
              </div>
      `;
    });

    return kidHtml;
  }

  html += `
      <ul class="nodes">
        ${generaHtml(children, level)}
      </ul>
    `;

  return html;
};

function calculateMaxChildren(data) {
    let maxChildrenCount = 0;

    for (let node of data) {
        let childrenCount = 0;

        // 递归计算子节点的数量
        if (node.children) {
            childrenCount += calculateMaxChildren(node.children);
        }

        // 计算当前节点及其子节点的子节点数量
        childrenCount += (node.children ? node.children.length : 0);
        
        // 更新最大子节点数量
        maxChildrenCount = Math.max(maxChildrenCount, childrenCount);
    }

    return maxChildrenCount;
}
const methodChart = () => {
  G6.registerNode(
    "dom-node",
    {
      draw(cfg, group) {
        const container = document.createElement("div");
        if (cfg.level2 === 0) {
          container.innerHTML = `
              <div class="boxChartTop" id="${cfg.id}">
                ${getTopHtml(cfg)}
                <div class="center-line"></div>
                ${generateSonTopHtml(cfg.positionList, true)}
              </div>`;
        } else {
          container.innerHTML = `
              <div class="boxChart" id="${
                cfg.id
              }">
                <div class="circle-wrap">
                  <div class="outermost-line">
                    <div class="bottom-line"></div>
                  </div>
                  <div class="circle-style">${
                    isCn && cfg.nameZh
                      ? cfg.nameZh
                      : isArabic && cfg.nameAr
                      ? cfg.nameAr
                      : cfg.nameEn
                  }</div>
                </div>
                ${generateSonHtml(cfg.positionList, true)}
              </div>
            `;
        }
        // 将container插入隐藏容器以计算宽高
        const hiddenContainer = document.getElementById("hiddenContainer");
        hiddenContainer.appendChild(container);
        const width = container.clientWidth;
        const height = container.clientHeight;
        hiddenContainer.removeChild(container);

        const shape = group.addShape("dom", {
          attrs: {
            width,
            height,
            x: 0,
            y: 0,
            html: container.innerHTML,
            size: [width, height],
          },
          draggable: true,
        });

        cfg.width = width;
        cfg.height = height;

        return shape;
      },
    },
    // },
    "dom"
  );

  G6.registerEdge("flow-line", {
    draw(cfg, group) {
      let startPoint = cfg.startPoint;
      let endPoint = cfg.endPoint;

      // 计算源节点底部中间位置
      const sourceModel = graph.findById(cfg.source).getModel();
      const sourceWidth = sourceModel.width;
      const sourceHeight = sourceModel.height;

      // const sourceContainer = document.getElementById(cfg.source);
      // const sourceWidth = sourceContainer.offsetWidth;
      // const sourceHeight = sourceContainer.offsetHeight;

      // 目标节点
      const targetModel = graph.findById(cfg.target).getModel();
      const targetWidth = targetModel.width;
      const targetHeight = targetModel.height;

      // const targetContainer = document.getElementById(cfg.target);
      // const targetWidth = targetContainer.offsetWidth;
      // const targetHeight = targetContainer.offsetHeight;
      
      const list = calculateMaxChildren(sourceModel.positionList)
      // 计算父节点底部中间位置
      let sourceX = startPoint.x
      if (sourceModel.level2 === 0 && sourceModel.positionList?.length > 0 && sourceModel.children?.length < 3) {
        console.log('1')
        sourceX = startPoint.x - 115
      } else if (sourceModel.level2 === 0 && sourceModel.positionList?.length > 0 && list < 3) {
        console.log('2')
        sourceX = startPoint.x - 150
      } else if (sourceModel.level2 === 0 && sourceModel.positionList?.length > 0 && list >= 3) {
        console.log('3')
        sourceX =  startPoint.x - (list * 60)
      }
      
      const sourceY = startPoint.y + sourceHeight / 2;

      // 计算目标节点顶部中间位置
      const targetX = endPoint.x;
      const targetY = endPoint.y - targetHeight / 2;

      const isSafari = /^((?!chrome|android).)*safari/i.test(
        navigator.userAgent
      );

      // console.log("sourceX:", sourceX, "sourceY:", sourceY);
      // console.log("targetX:", sourceX, "targetY:", sourceY);
      // console.log("--------------------------------");

      if (isSafari) {
        // startPoint = {
        //   x: cfg.startPoint.x * 7.434782608695652,
        //   y: cfg.startPoint.y * 2.295,
        // };
        // endPoint = {
        //   x: cfg.endPoint.x * 1.834874504623514,
        //   y: cfg.endPoint.y * 1.060887512899897,
        // };
      }

      // 控制连接线的路径，使其从父节点底部中间连接到子节点顶部中间
      const path = [
        ["M", sourceX, sourceY - 15],
        ["L", sourceX, (sourceY + targetY) / 2],
        ["L", targetX, (sourceY + targetY) / 2],
        ["L", targetX, targetY],
      ];

      // 绘制连接线
      const shape = group.addShape("path", {
        attrs: {
          path: path,
          stroke: "#e07572",
          lineWidth: 1.5,
        },
      });

      return shape;
    },
  });
};

let index = 0;
const treeChart = () => {
  methodChart();
  const width = graphContainer.value.scrollWidth || 1740;
  const height = graphContainer.value.scrollHeight || 700;
  // const width = 1740;
  // const height = 700;

  graph = new G6.TreeGraph({
    container: graphContainer.value,
    width,
    height,
    // fitCenter: true,
    renderer: "svg",
    fitView: true,
    linkCenter: true,
    // maxZoom: props.treeData[0].children.length === 1 ? 1 : '',
    modes: {
      default: ["drag-canvas", "zoom-canvas"],
    },
    defaultNode: {
      type: "dom-node",
      // size: [100, 40], // 设置节点大小
      // style: {
      //   fill: "#e07572",
      //   stroke: "#e07572",
      // },
    },
    defaultEdge: {
      type: "flow-line",
      style: {
        stroke: "#e07572",
        lineWidth: 1.5,
      },
    },
    layout: {
      type: "compactBox",
      direction: "TB",
      getId: function getId(d) {
        return d.id;
      },
      getHeight: function getHeight(d) {
        return d.height || 200;
      },
      getWidth: function getWidth(d) {
        return d.width || 16;
        // return 16;
      },
      // 每个节点的垂直间隙
      getVGap: function getVGap(d) {
        return 50;
      },
      // 每个节点的水平间隙
      getHGap: function getHGap() {
        return 70;
      },
    },
  });

  graph.read(props.treeData[0]);
  graph.clear();

  // 在首次渲染后获取节点实际宽高并重新布局
  setTimeout(() => {
    graph.read(props.treeData[0]);
    graph.fitView();
  }, 650);

  // graph.changeData(props.treeData[0]);

  // graph.updateLayout({
  //   getHeight: function getHeight(d) {
  //     const height = tmpData[d.id] ? tmpData[d.id].height : 200;
  //     console.log("height:", height);
  //     return height;
  //   },
  // });

  // setTimeout(() => {
  //   graph.changeData(props.treeData[0]);
  //   graph.fitView();
  // }, 500);

  if (typeof window !== "undefined")
    window.onresize = () => {
      if (!graph || graph.get("destroyed")) return;
      if (
        !graphContainer.value ||
        !graphContainer.value.scrollWidth ||
        !graphContainer.value.scrollHeight
      )
        return;
      graph.changeSize(
        graphContainer.value.scrollWidth,
        graphContainer.value.scrollHeight
      );
    };
};

const downImage = async () => {
  graph.fitView(); // 确保视图包含所有节点和边
  setTimeout(() => {
    domtoimage
      .toSvg(graphContainer.value)
      .then(function (dataUrl) {
        const link = document.createElement("a");
        link.href = dataUrl;
        link.download = "tree-graph";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }).catch(function (error) {
        console.error("oops, something went wrong!", error);
      });
    // htmlToPDF('graphContainer', 'html')
  }, 200);
};

const downPdf = () => {
  graph.fitView();  // 确保视图包含所有节点和边
  // let target = document.getElementById("graphContainer");
  const target = graphContainer.value;
  console.log('dddd', target)

  let contentWidth = target.clientWidth; // 获得该容器的宽
  let contentHeight = target.clientHeight; // 获得该容器的高
  console.log('contentWidth', contentWidth)
  console.log('contentHeight', contentHeight)

  target.ownerDocument.defaultView.devicePixelRatio = 1.25;
  target.ownerDocument.defaultView.innerWidth = contentWidth;
  target.ownerDocument.defaultView.innerHeight = contentHeight;

  let opts = {
    scale: 4,
    width: contentWidth,
    height: contentHeight,
    useCORS: true,
    bgcolor: "#fff",
  };
  domtoimage
    .toPng(target, opts)
    .then(function (dataUrl) {
      var img = new Image();
      img.src = dataUrl;
      //一页pdf显示html页面生成的canvas高度;
      var pageHeight = (contentWidth / 592.28) * 841.89;
      //未生成pdf的html页面高度
      var leftHeight = contentHeight;
      //页面偏移
      var position = 0;
      //a4纸的尺寸[595.28,841.89]，html页面生成的canvas在pdf中图片的宽高
      var imgWidth = 595.28;
      var imgHeight = (592.28 / contentWidth) * contentHeight;

      var pdf = new jsPDF("", "pt", "a4");

      //有两个高度需要区分，一个是html页面的实际高度，和生成pdf的页面高度(841.89)
      //当内容未超过pdf一页显示的范围，无需分页
      if (leftHeight < pageHeight) {
        pdf.addImage(dataUrl, "PNG", 0, 0, imgWidth, imgHeight);
      } else {
        while (leftHeight > 0) {
          pdf.addImage(dataUrl, "PNG", 0, position, imgWidth, imgHeight);
          leftHeight -= pageHeight;
          position -= 841.89;
          //避免添加空白页
          if (leftHeight > 0) {
            pdf.addPage();
          }
        }
      }

      pdf.save("tree-graph.pdf");
    })
    .catch(function (error) {
      console.error("oops, something went wrong!", error);
    });
}


const downPdf2 = () => {
  graph.fitView();  // 确保视图包含所有节点和边
  const svgElement = document.querySelector("#graphContainer svg");
  svgElement.innerHTML += `
    <style>
      .boxChart {
        display: flex;
        flex-direction: column;
        align-items: center;
        user-select: none;
        height: 100%;
      }

      .boxChart .circle-wrap {
        display: flex;
        width: 100%;
      }

      .boxChart .circle-style {
        width: 100%;
        height: 80px;
        padding: 16px;
        margin-bottom: 0;
        border-radius: 0;
        border: 1px solid #242424;
        background-color: #fff2cc;
        text-align: center;
        word-wrap: break-word;
        font-size: 20px;
        font-weight: bold;
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .boxChart .diamond-style {
        border: 1px solid #242424;
        border-right: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChart .nodes {
        list-style: none;
      }

      .boxChart .nodes .outermost {
        display: flex;
        overflow: hidden;
      }

      .boxChart .nodes .outermost .outermost-line .top-line {
        width: 10px;
        height: 35px;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChart .nodes .outermost .outermost-line .bottom-line {
        width: 0;
        height: 5000%;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChart .nodes .hierarchy {
        padding-bottom: 20px;
      }

      .boxChart .nodes .hierarchy .square-wrap {
        display: flex;
        padding-top: 20px;
      }

      .boxChart .nodes .hierarchy .square-wrap:last-child {
        margin-bottom: 0;
      }

      .boxChart .nodes .square-wrap .line {
        margin-top: -21px;
      }

      .boxChart .nodes .square-wrap .line .top-line {
        width: 10px;
        height: 35px;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChart .nodes .square-wrap .line .bottom-line {
        width: 0;
        height: 5000%;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChart .nodes .nodes {
        padding-left: 60px;
      }

      .boxChart .square-style {
        display: flex;
        background-color: #fff;
      }

      .boxChart .square-style .square-style-left {
        display: flex;
        flex-direction: column;
      }

      .boxChart .square-style .square-style-left .square-style-left-top {
        border: 1px solid #242424;
        border-right: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChart .square-style .square-style-left .square-style-left-bottom {
        border: 1px solid #242424;
        border-right: none;
        border-top: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChart .square-style .square-style-right {
        width: 200px;
        height: auto;
        text-align: center;
      }

      .boxChart .square-style .square-style-right .square-style-right-top {
        border: 1px solid #242424;
        padding: 8px;
      }

      .boxChart
      .square-style
      .square-style-right
      .square-style-right-bottom {
        border: 1px solid #242424;
        border-top: none;
        padding: 4px 0;
      }

      .boxChartTop {
        display: flex;
        flex-direction: column;
        align-items: center;
        user-select: none;
        padding-right: 32px;
      }

      .boxChartTop .circle-wrap {
        display: flex;
        width: 100%;
        margin-left: -40px;
      }

      .boxChartTop .center-top {
        width: 100%;
        display: flex;
        align-items: center;
      }

      .boxChartTop .diamond-style {
        display: flex;
        flex-direction: column;
      }

      .boxChartTop .diamond-style .diamond-top {
        border: 1px solid #242424;
        border-right: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChartTop .diamond-style .diamond-bottom {
        border: 1px solid #242424;
        border-right: none;
        border-top: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChartTop .nodes {
        list-style: none;
        padding-left: 50px;
      }

      .boxChartTop .nodes .outermost {
        display: flex;
        overflow: hidden;
      }

      .boxChartTop .nodes .outermost .outermost-line .top-line {
        width: 10px;
        height: 35px;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChartTop .nodes .outermost .outermost-line .top-line0 {
        width: 10px;
        height: 35px;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 0;
      }

      .boxChartTop .nodes .outermost .outermost-line .bottom-line {
        width: 0;
        height: 5000%;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChartTop .nodes .hierarchy {
        padding-bottom: 21px;
        overflow: hidden;
      }

      .boxChartTop .nodes .hierarchy .square-wrap {
        display: flex;
        padding-top: 20px;
      }

      .boxChartTop .nodes .hierarchy .square-wrap:last-child {
        margin-bottom: 0;
      }

      .boxChartTop .node .square-wrap .line {
        margin-top: -21px;
      }
      .boxChartTop .node .square-wrap .top-line {
        width: 10px;
        height: 35px;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }
      .boxChartTop .node .square-wrap .bottom-line {
        width: 0;
        height: 5000%;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
      }

      .boxChartTop .nodes .nodes {
        padding-left: 60px;
      }

      .boxChartTop .center-line {
        width: 0;
        height: 20px;
        border-color: rgba(217, 83, 79, 0.8);
        border-style: solid;
        border-width: 0 0 2px 2px;
        margin-bottom: -20px;
      }

      .boxChartTop .square-style {
        display: flex;
        background-color: #fff;
      }

      .boxChartTop .square-style .square-style-left {
        display: flex;
        flex-direction: column;
      }

      .boxChartTop .square-style .square-style-left .square-style-left-top {
        border: 1px solid #242424;
        border-right: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChartTop
      .square-style
      .square-style-left
      .square-style-left-bottom {
        border: 1px solid #242424;
        border-right: none;
        border-top: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }

      .boxChartTop .square-style .square-style-right {
        width: 200px;
        height: auto;
        text-align: center;
      }

      .boxChartTop
      .square-style
      .square-style-right
      .square-style-right-top {
        border: 1px solid #242424;
        padding: 8px;
      }

      .boxChartTop
      .square-style
      .square-style-right
      .square-style-right-bottom {
        border: 1px solid #242424;
        border-top: none;
        padding: 4px 0;
      }

      .boxChartTop .top-right {
        margin-left: -41px;
      }

      .boxChartTop .top-box-htm {
        display: flex;
        width: 100%;
        margin-left: 135px;
      }

      .boxChartTop .top-box-html .tox-box-diamond {
        width: 200px;
        height: auto;
        text-align: center;
      }

      .diamond-title {
        color: #ffffff;
        border: 1px solid #242424;
        background-color: #4f5b72;
        padding: 8px;
      }

      .boxChartTop .top-box-html .tox-box-diamond .diamond-name {
        border: 1px solid #242424;
        border-top: none;
        padding: 4px 0;
      }

      .positionGreen {
        background-color: #6fc9c2;
      }
      .positionOrange {
        background-color: #f2f09f;
      }
    </style>
  `

  const target = graphContainer.value;

  let contentWidth = target.clientWidth; // 获得该容器的宽
  let contentHeight = target.clientHeight; // 获得该容器的高

  target.ownerDocument.defaultView.devicePixelRatio = 1.25;
  target.ownerDocument.defaultView.innerWidth = contentWidth;
  target.ownerDocument.defaultView.innerHeight = contentHeight;

  let opts = {
    scale: 5,
    width: contentWidth,
    height: contentHeight,
    useCORS: true,
  };

  html2canvas(target, opts).then(function (canvas) {
    //一页pdf显示html页面生成的canvas高度;
    var pageHeight = (contentWidth / 592.28) * 841.89;
    //未生成pdf的html页面高度
    var leftHeight = contentHeight;
    //页面偏移
    var position = "0 10px !important";
    //a4纸的尺寸[595.28,841.89]，html页面生成的canvas在pdf中图片的宽高
    var imgWidth = 595.28;
    var imgHeight = (841.89 / contentWidth) * contentHeight;

    var pageData = canvas.toDataURL("image/jpeg", 1.0);

    var pdf = new jsPDF("p", "pt", "a4");

    //有两个高度需要区分，一个是html页面的实际高度，和生成pdf的页面高度(841.89)
    //当内容未超过pdf一页显示的范围，无需分页
    if (leftHeight < pageHeight) {
      pdf.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight);
    } else {
      while (leftHeight > 0) {
        pdf.addImage(pageData, "JPEG", 0, position, imgWidth, imgHeight);
        leftHeight -= pageHeight;
        position -= 841.89;
        //避免添加空白页
        if (leftHeight > 0) {
          pdf.addPage();
        }
      }
    }

    pdf.save("tree-graph.pdf");
  })
  .catch(function (error) {
    console.error("html2canvas 捕获的错误:", error);
  });
}

onUnmounted(() => {
  // 销毁图实例
  if (graph) {
    graph.clear();
    graph.destroy();
  }
});

const closeChart = () => {
  if (graph) {
    graph.clear();
    graph.destroy();
  }
};
defineExpose({
  treeChart,
  downImage,
  downPdf,
  // convertToPDF,
  closeChart,
});
</script>

<style lang="scss">
.boxChart {
  display: flex;
  flex-direction: column;
  align-items: center;
  user-select: none;
  height: 100%;
  .circle-wrap {
    display: flex;
    width: 100%;
  }

  .circle-style {
    width: 100%;
    height: 80px;
    padding: 16px;
    margin-bottom: 0;
    border-radius: 0;
    border: 1px solid #242424;
    background-color: #fff2cc;
    text-align: center;
    word-wrap: break-word;
    font-size: 20px;
    font-weight: bold;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .diamond-style {
    display: flex;
    flex-direction: column;
    .diamond-top {
      border: 1px solid #242424;
      border-right: none;
      width: 50px;
      height: 28px;
      line-height: 28px;
      text-align: center;
    }
    .diamond-bottom {
      border: 1px solid #242424;
      border-right: none;
      width: 50px;
      height: 28px;
      line-height: 28px;
      text-align: center;
    }
  }

  .nodes {
    list-style: none;
    .outermost {
      display: flex;
      overflow: hidden;
      .outermost-line {
        .top-line {
          width: 10px;
          height: 35px;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
        .bottom-line {
          width: 0;
          height: 5000%;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
      }
    }

    .hierarchy {
      padding-bottom: 20px;
      overflow: hidden;

      .square-wrap {
        display: flex;
        padding-top: 20px;
        &:last-child {
          margin-bottom: 0;
        }
      }
    }

    .square-wrap {
      .line {
        margin-top: -21px;
        .top-line {
          width: 10px;
          height: 35px;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
        .bottom-line {
          width: 0;
          height: 5000%;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
      }
    }

    .nodes {
      padding-left: 60px;
    }
  }

  .square-style {
    display: flex;
    background-color: #fff;
    &-left {
      display: flex;
      flex-direction: column;
      &-top {
        border: 1px solid #242424;
        border-right: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }
      &-bottom {
        border: 1px solid #242424;
        border-right: none;
        border-top: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }
    }
    &-right {
      width: 200px;
      height: auto;
      text-align: center;
      &-top {
        border: 1px solid #242424;
        padding: 8px;
      }
      &-bottom {
        border: 1px solid #242424;
        border-top: none;
        padding: 4px 0;
      }
    }
  }
}
.boxChartTop {
  display: flex;
  flex-direction: column;
  align-items: center;
  user-select: none;
  padding-right: 32px;
  .circle-wrap {
    display: flex;
    width: 100%;
    margin-left: -40px;
  }
  .center-top {
    // border: 1px solid red;
    width: 100%;
    display: flex;
    align-items: center;
  }
  .top-vertical {
    flex: 1;
    width: 0;
    height: 100%;
    border-color: rgba(217, 83, 79, 0.8);
    border-style: solid;
    border-width: 0 0 2px 2px;
    margin-left: 42.8%;
  }
  .diamond-style {
    display: flex;
    flex-direction: column;
    .diamond-top {
      border: 1px solid #242424;
      border-right: none;
      width: 50px;
      height: 28px;
      line-height: 28px;
      text-align: center;
    }
    .diamond-bottom {
      border: 1px solid #242424;
      border-right: none;
      border-top: none;
      width: 50px;
      height: 28px;
      line-height: 28px;
      text-align: center;
    }
  }
  .nodes {
    list-style: none;
    padding-left: 60px !important;
    .outermost {
      display: flex;
      overflow: hidden;
      .outermost-line {
        .top-line {
          width: 10px;
          height: 35px;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
        .top-line0 {
          width: 10px;
          height: 35px;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 0;
        }
        .bottom-line {
          width: 0;
          height: 5000%;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
      }
    }

    .hierarchy {
      padding-bottom: 21px;
      overflow: hidden;
      .square-wrap {
        display: flex;
        padding-top: 20px;
        &:last-child {
          margin-bottom: 0;
        }
      }
    }

    .square-wrap {
      .line {
        margin-top: -21px;
        .top-line {
          width: 10px;
          height: 35px;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
        .bottom-line {
          width: 0;
          height: 5000%;
          border-color: rgba(217, 83, 79, 0.8);
          border-style: solid;
          border-width: 0 0 2px 2px;
        }
      }
    }

    .nodes {
      padding-left: 60px;
      // display: flex;
    }
  }
  .center-line {
    width: 0;
    height: 20px;
    border-color: rgba(217, 83, 79, 0.8);
    border-style: solid;
    border-width: 0 0 2px 2px;
    margin-bottom: -20px;
  }
  .square-style {
    display: flex;
    background-color: #fff;
    &-left {
      display: flex;
      flex-direction: column;
      &-top {
        border: 1px solid #242424;
        border-right: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }
      &-bottom {
        border: 1px solid #242424;
        border-right: none;
        border-top: none;
        width: 50px;
        height: 28px;
        line-height: 28px;
        text-align: center;
      }
    }
    &-right {
      width: 200px;
      height: auto;
      text-align: center;
      &-top {
        border: 1px solid #242424;
        padding: 8px;
      }
      &-bottom {
        border: 1px solid #242424;
        border-top: none;
        padding: 4px 0;
      }
    }
  }
  .top-right {
    margin-left: -41px;
  }
}

.top-box-html {
  display: flex;
  width: 100%;
  margin-left: 135px;
  .tox-box-diamond {
    width: 200px;
    height: auto;
    text-align: center;
    .diamond-title {
      border: 1px solid #242424;
      background-color: #4f5b72;
      color: #fff;
      padding: 8px;
    }
    .diamond-name {
      border: 1px solid #242424;
      border-top: none;
      padding: 4px 0;
    }
  }
}

.positionGreen {
  background-color: #6fc9c2;
}
.positionOrange {
  background-color: #f2f09f;
}
</style>
